home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1993 July / InfoMagic USENET CD-ROM July 1993.ISO / sources / misc / volume9 / tbench < prev    next >
Encoding:
Text File  |  1989-11-12  |  60.1 KB  |  2,316 lines

  1. Newsgroups: comp.sources.misc
  2. from: allbery@uunet.UU.NET (Brandon S. Allbery - comp.sources.misc)
  3. subject: v09i004: TBENCH - tty benchmark programs
  4. Reply-To: gene@digibd (Gene H. Olson)
  5.  
  6. Posting-number: Volume 9, Issue 4
  7. Submitted-by: gene@digibd (Gene H. Olson)
  8. Archive-name: tbench
  9.  
  10. This is a set of benchmark programs to test the performance of
  11. UNIX tty subsystems under load.  It was developed by a vendor
  12. of multi-port communication boards; there may be some bias.
  13.  
  14. #! /bin/sh
  15. # This is a shell archive.  Remove anything before this line, then unpack
  16. # it by saving it into a file and typing "sh file".  To overwrite existing
  17. # files, type "sh file -c".  You can also feed this as standard input via
  18. # unshar, or by typing "sh <file", e.g..  If this archive is complete, you
  19. # will see the following message at the end:
  20. #        "End of shell archive."
  21. # Contents:  README cpu.c ibench iprint islave obench oprint perf.c
  22. # Wrapped by gene@digibd on Sun Nov 12 18:29:48 1989
  23. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  24. if test -f README -a "${1}" != "-c" ; then 
  25.   echo shar: Will not over-write existing file \"README\"
  26. else
  27. echo shar: Extracting \"README\" \(23749 characters\)
  28. sed "s/^X//" >README <<'END_OF_README'
  29. X####################################################
  30. X#     This software released to the public domain  #
  31. X#     without restrictions of any kind.            #
  32. X####################################################
  33. X
  34. X             @(#)README    3.4 11/12/89
  35. X
  36. XThe programs included in this, the first release of TBENCH
  37. Xwere all developed by DigiBoard Incorporated (St. Louis Pk, MN)
  38. Xfor internal performance testing.  DigiBoard used these to
  39. Xtest their own, and competitors multiport communication
  40. Xboards.  Some of those results have been published in trade
  41. Xmagazines.
  42. X
  43. XThese benchmarks are a another attempt at developing objective
  44. Xbenchmarks to compare the performance of tty subsystems under
  45. Xextreme load.  An earlier benchmark suite developed by ANVIL
  46. X(Australia) was posted to comp.sys.i386 some time ago.  Those
  47. Xwere a fine first attempt, but did suffer from some limitations.
  48. X
  49. XAt DigiBoard, we believe these benchmarks provide a much
  50. Xbetter indication of steady state tty I/O performance.
  51. XIn particular they send data for a length of time before
  52. Xbenchmarking begins, and after it completes, so that the
  53. Xresults are closer to indicating steady-state performance.
  54. XThey also check input data automatically, and provide a
  55. Xsummary of the errors detected.
  56. X
  57. XDigiBoard has made an attempt to keep these benchmarks as
  58. Xobjective as possible.   However DigiBoard is a for-profit
  59. Xcompany, and as such must have included some bias.  Anyone
  60. Xusing these benchmarks is heartily encouraged to analyze
  61. Xthem, improve them, and if they see fit, to criticize them
  62. Xas needed.
  63. X
  64. XThese programs have been tested on essentially all UNIX
  65. Xports to 286/386 PC-compatible systems, and also on Suns.
  66. X
  67. XSend bug fixes, enhancements, comments (and flames) to:
  68. X
  69. XGene H. Olson                  uunet!digibd!gene
  70. XMember of Technical Staff
  71. XDigiBoard Inc.
  72. XSt. Louis Park, MN             (612) 922-8055
  73. X
  74. X------------------------------------------------------------
  75. X
  76. XThe remainder of this file describes how to use the terminal
  77. Xbenchmark programs.  We assume the reader is an experienced
  78. XUNIX user, thoroughly familiar with the concept of tty devices
  79. Xand modes, and very comfortable at the UNIX command level.
  80. XNovice UNIX users may find these notes incomprehensible.
  81. X
  82. X
  83. XTHE PROGRAMS
  84. X------------
  85. X
  86. XBefore you can use these benchmarks, you need to compile two
  87. Xprograms, and run one of them to calibrate it for use on your
  88. Xsystem.  Enter the following commands:
  89. X
  90. X                    cc -o perf -O perf.c
  91. X                    cc -o cpu cpu.c
  92. X                    ./cpu -c
  93. X
  94. XWhen compiling perf.c and cpu.c you are wise to make sure your
  95. Xsystem is using setvbuf() with the correct parameter sequence.
  96. XThe original UNIX 5.2 release had parameters 2 and 3 reversed
  97. Xfrom the setbuf(3) manual page, and from subsequent releases of
  98. XUNIX.  However while the manual pages were different, the lint(1)
  99. Xlibrary file was consistent with the way the parameters were
  100. Xactually used.  I suggest you run lint on these programs before
  101. Xattempting to use them.  If you get an error on the setvbuf()
  102. Xdeclaration, then use instead:
  103. X
  104. X               cc -DSETVBUF -o perf -O perf.c
  105. X               cc -DSETVBUF -o cpu cpu.c
  106. X               ./cpu -c
  107. X
  108. XThe programs now available include:
  109. X
  110. Xperf      C program which may be invoked for either input or
  111. X          output testing.
  112. X
  113. X          In output mode, the program writes 6 digit numbers
  114. X          (plus checksum) to standard output, which should be
  115. X          redirected to the tty under test.  The program reports
  116. X          the output speed, real (elapsed) time, and system
  117. X          time consumed.
  118. X
  119. X          In input mode, perf reads the output of another perf
  120. X          in output mode, redirected through a pair of tty ports.
  121. X          The program compares the actual data received to the
  122. X          expected input and reports error statistics.  The
  123. X          report includes the speed of input, real time, system
  124. X          time, the number of codes missing or in error, and
  125. X          the number of stray characters received.
  126. X
  127. X
  128. Xcpu       C program to determine how busy the system is during
  129. X          input/output testing.
  130. X
  131. X          This program must first be run on an idle system to
  132. X          calibrate its internal loop.  Thereafter it may be
  133. X          invoked to drop its priority and absorb all available
  134. X          idle time.  Using a combination of reported system time
  135. X          and its own internally calibrated loop, it displays
  136. X          the amount of CPU time consumed elsewhere at both
  137. X          process and interrupt levels.
  138. X
  139. X          The assignment of time to process and interrupt levels
  140. X          is very approximate, but the total is an accurate
  141. X          reflection of the CPU being utilized by other programs.
  142. X          If the only other programs running are the terminal
  143. X          benchmarks, the results are quite good.
  144. X
  145. X          If your system contains memory of different speeds,
  146. X          this program may report grossly inaccurate results.
  147. X          There is no solution, except to change memory boards
  148. X          or move to another system.
  149. X
  150. X
  151. Xobench    A shell file to supervise output testing.
  152. X
  153. X          The program takes as parameters a list of ttys,
  154. X          test modes and baud rates.  It runs the perf program
  155. X          on 1 to n of these terminals in all of the mode and
  156. X          baud rate combinations given.  The results of these
  157. X          tests are written to standard output, and should be
  158. X          captured to a file.
  159. X
  160. X
  161. Xoprint    A shell file to summarize the results reported by
  162. X          the obench shell file above.
  163. X
  164. X
  165. Xislave    A shell file to monitor input terminals and report
  166. X          the speed and accuracy of the input actually received.
  167. X
  168. X          This program takes as parameters a baud rate,
  169. X          and a list of terminals to be monitored.  The
  170. X          data coming into the terminals may include test
  171. X          commands and data supplied by the ibench program
  172. X          below.  The results are written to standard output,
  173. X          and should be captured to a file.
  174. X
  175. X
  176. Xibench    A shell file to supervise input testing and to produce
  177. X          test data for by the islave program above.
  178. X
  179. X          Ibench takes as parameters a list of ttys, test modes,
  180. X          and baud rates.  It runs the perf program to write
  181. X          test commands and data to the given ttys. These
  182. X          ttys are then connected to terminals monitored by the
  183. X          islave program above.
  184. X
  185. X          The commands sent out by ibench cause the islave program
  186. X          to print messages, change input modes and baud rates
  187. X          as the test progresses.
  188. X
  189. X
  190. Xiprint    A shell file to summarize the results reported by
  191. X          the islave shell file above.
  192. X
  193. X
  194. X
  195. XOUTPUT TEST PROCEDURE
  196. X---------------------
  197. X
  198. XOutput testing is straightforward, and requires minimal hardware
  199. Xsetup.
  200. X
  201. XThe benchmark writes data out to multiple ports as fast as possible,
  202. Xwithout flow control, so it is not necessary to hookup the cables to
  203. Xterminals.
  204. X
  205. XTo perform the test on a DigiBoard PC/8e under SCO Xenix, type
  206. Xthe following command on the system console:
  207. X
  208. X    obench 9600 exta extb opost -opost /dev/ttyi1[a-h] | tee junk
  209. X
  210. XThis command outputs data at baud rates 9600, exta (19200),
  211. Xand extb (38400) to the given ports in both opost (cooked) and
  212. X-opost (raw) modes.  All combinations of baud rates and modes
  213. Xare tested, using 1-8 terminals each.  This yields a total of 3 baud
  214. Xrates * 2 modes * 8 terminals = 48 different tests, each writing
  215. Xabout 100K characters to 1 or more terminals.
  216. X
  217. XIf all goes well, the test takes about 2 hours.  The test output
  218. Xis displayed on the terminal and written to the file junk.  The
  219. Xoutput should look similar to:
  220. X
  221. XTEST tty=1, baud=9600, mode=opost
  222. XTIME process=5.7, interrupt=-0.1, total=5.6
  223. X/dev/ttyi1a : OUT cps=965, real=103.58, user=0.4, sys=5.1
  224. XTEST tty=2, baud=9600, mode=opost
  225. XTIME process=11.3, interrupt=-0.1, total=11.2
  226. X/dev/ttyi1b : OUT cps=965, real=103.54, user=0.5, sys=5.1
  227. X/dev/ttyi1a : OUT cps=965, real=103.54, user=0.4, sys=4.9
  228. XTEST tty=3, baud=9600, mode=opost
  229. XTIME process=16.1, interrupt=0.5, total=16.6
  230. X/dev/ttyi1b : OUT cps=965, real=103.58, user=0.4, sys=5.0
  231. X/dev/ttyi1c : OUT cps=965, real=103.56, user=0.5, sys=5.2
  232. X/dev/ttyi1a : OUT cps=965, real=103.56, user=0.3, sys=5.0
  233. XTEST tty=4, baud=9600, mode=opost
  234. XTIME process=21.7, interrupt=0.7, total=22.3
  235. X/dev/ttyi1b : OUT cps=965, real=103.56, user=0.4, sys=5.1
  236. X/dev/ttyi1c : OUT cps=965, real=103.56, user=0.6, sys=5.0
  237. X/dev/ttyi1d : OUT cps=965, real=103.62, user=0.4, sys=5.0
  238. X/dev/ttyi1a : OUT cps=965, real=103.62, user=0.4, sys=5.0
  239. XTEST tty=5, baud=9600, mode=opost
  240. XTIME process=28.3, interrupt=-0.3, total=27.9
  241. X/dev/ttyi1b : OUT cps=965, real=103.60, user=0.6, sys=5.1
  242. X/dev/ttyi1d : OUT cps=965, real=103.56, user=0.4, sys=5.0
  243. X/dev/ttyi1e : OUT cps=965, real=103.56, user=0.6, sys=5.1
  244. X/dev/ttyi1a : OUT cps=965, real=103.60, user=0.5, sys=5.1
  245. X/dev/ttyi1c : OUT cps=963, real=103.82, user=0.6, sys=4.8
  246. XTEST tty=6, baud=9600, mode=opost
  247. XTIME process=32.4, interrupt=1.0, total=33.5
  248. X/dev/ttyi1c : OUT cps=964, real=103.64, user=0.5, sys=4.8
  249. X/dev/ttyi1f : OUT cps=965, real=103.56, user=0.6, sys=5.1
  250. X/dev/ttyi1a : OUT cps=965, real=103.60, user=0.4, sys=5.0
  251. X/dev/ttyi1e : OUT cps=965, real=103.56, user=0.4, sys=5.2
  252. X/dev/ttyi1b : OUT cps=965, real=103.56, user=0.5, sys=4.8
  253. X/dev/ttyi1d : OUT cps=965, real=103.56, user=0.6, sys=4.9
  254. XTEST tty=7, baud=9600, mode=opost
  255. XTIME process=36.8, interrupt=3.1, total=39.9
  256. X/dev/ttyi1d : OUT cps=965, real=103.62, user=0.4, sys=5.1
  257. X/dev/ttyi1f : OUT cps=964, real=103.70, user=0.4, sys=5.1
  258. X/dev/ttyi1b : OUT cps=957, real=104.48, user=0.5, sys=4.9
  259. X/dev/ttyi1g : OUT cps=964, real=103.72, user=0.4, sys=4.9
  260. X/dev/ttyi1c : OUT cps=962, real=103.94, user=0.4, sys=5.0
  261. X/dev/ttyi1a : OUT cps=964, real=103.64, user=0.5, sys=4.9
  262. X/dev/ttyi1e : OUT cps=958, real=104.34, user=0.7, sys=5.0
  263. XTEST tty=8, baud=9600, mode=opost
  264. XTIME process=45.0, interrupt=0.5, total=45.5
  265. X/dev/ttyi1a : OUT cps=961, real=103.96, user=0.6, sys=4.9
  266. X/dev/ttyi1d : OUT cps=963, real=103.78, user=0.6, sys=5.1
  267. X/dev/ttyi1f : OUT cps=964, real=103.66, user=0.5, sys=5.1
  268. X/dev/ttyi1c : OUT cps=963, real=103.74, user=0.6, sys=5.1
  269. X/dev/ttyi1h : OUT cps=957, real=104.46, user=0.5, sys=5.1
  270. X/dev/ttyi1b : OUT cps=955, real=104.70, user=0.4, sys=4.8
  271. X/dev/ttyi1g : OUT cps=963, real=103.80, user=0.4, sys=5.1
  272. X/dev/ttyi1e : OUT cps=964, real=103.68, user=0.6, sys=5.0
  273. XTEST tty=1, baud=9600, mode=-opost
  274. XTIME process=1.6, interrupt=0.0, total=1.6
  275. X/dev/ttyi1a : OUT cps=960, real=104.16, user=0.5, sys=1.1
  276. XTEST tty=2, baud=9600, mode=-opost
  277. XTIME process=2.9, interrupt=0.2, total=3.1
  278. X/dev/ttyi1b : OUT cps=959, real=104.18, user=0.5, sys=0.9
  279. X/dev/ttyi1a : OUT cps=960, real=104.14, user=0.4, sys=0.9
  280. XTEST tty=3, baud=9600, mode=-opost
  281. X                       ...
  282. X
  283. XWhen the test is complete, you may summarize the data in tabular
  284. Xform by typing:
  285. X
  286. X          oprint junk
  287. X
  288. XThis prints a summary of the input received in tabular format with
  289. Xcolumn headers.  The output should resemble:
  290. X
  291. X ports     baud      mode        cps      real      %sys     %host
  292. X -----    ------    ------      -----    ------    -----     ----
  293. X    1      9600      opost      965.0     103.6      5.1     5.31
  294. X    2      9600      opost      965.0     103.5     10.2     5.31
  295. X    3      9600      opost      965.0     103.6     15.2     5.24
  296. X    4      9600      opost      965.0     103.6     20.4     5.28
  297. X    5      9600      opost      964.6     103.6     25.5     5.29
  298. X    6      9600      opost      964.8     103.6     30.6     5.29
  299. X    7      9600      opost      962.0     103.9     36.6     5.43
  300. X    8      9600      opost      961.3     104.0     41.7     5.42
  301. X
  302. X    1      9600     -opost      960.0     104.2      1.1     1.17
  303. X    2      9600     -opost      959.5     104.2      2.2     1.12
  304. X    3      9600     -opost      959.0     104.2      3.2     1.11
  305. X    4      9600     -opost      959.5     104.2      4.3     1.12
  306. X    5      9600     -opost      958.8     104.2      5.3     1.11
  307. X    6      9600     -opost      959.7     104.2      6.4     1.10
  308. X    7      9600     -opost      958.6     104.2      8.7     1.29
  309. X    8      9600     -opost      958.6     104.2      9.7     1.27
  310. X
  311. X    1     19200      opost     1919.0     104.2     10.2     5.29
  312. X    2     19200      opost     1922.0     104.0     20.4     5.31
  313. X    3     19200      opost     1921.7     104.0     30.5     5.28
  314. X    4     19200      opost     1920.8     104.1     40.6     5.29
  315. X    5     19200      opost     1920.4     104.1     50.8     5.29
  316. X    6     19200      opost     1920.2     104.1     61.0     5.30
  317. X    7     19200      opost     1919.6     104.2     71.5     5.32
  318. X    8     19200      opost     1917.4     104.3     81.3     5.30
  319. X
  320. X    1     19200     -opost     1921.0     104.1      2.1     1.07
  321. X        ...
  322. X
  323. X
  324. XThe columns printed are:
  325. X
  326. Xbaud    The test baud rate.
  327. X
  328. Xmode    The communication mode, either opost (cooked) or -opost
  329. X    (raw).
  330. X
  331. Xflow    The flow control mode, either ixon (output flow control)
  332. X    -ixon (no flow control).
  333. X
  334. Xcps    The character per second (cps) output speed actually measured.
  335. X    Under ideal conditions, this will be the baud rate divided
  336. X    by 10.  Lower numbers indicate a reduction in performance.
  337. X
  338. X%sys    Percent of system time used during the steady-state portion of
  339. X    the test.  This is computed by starting with 100%, subtracting
  340. X    the "perf" program user time, and the idle time measured by
  341. X    the "cpu" program.   Because it is a subtractive method, it
  342. X    is less accurate at lower loads, and progressively more
  343. X    accurate as the load increases.
  344. X
  345. X%host    Percent of system time used per kilo-character of output.
  346. X
  347. X
  348. XINPUT TEST PROCEDURE
  349. X--------------------
  350. X
  351. XInput testing is much harder than output testing.  To do a good job,
  352. Xyou need two systems, the system being tested, and another system
  353. Xto produce the test data.   You must cable the two systems together,
  354. Xand run programs on both systems.  In all, it is about 3 times as
  355. Xmuch work as the output test procedure.
  356. X
  357. XFor reference, call the system producing the test data the "producer",
  358. Xand the system under test the "consumer".   If you wish to test
  359. Xinput on 8 lines simultaneously, you must cable 8 ports on the
  360. Xproducer to 8 ports on the consumer system.   You will probably need
  361. Xa gender changer and a null modem connector for each line as well.
  362. X
  363. XMost intelligent cards will do output much faster than they do input,
  364. Xso generally the consumer system will overload before the producer
  365. Xsystem begins to slow down.  This is not always true however, so
  366. Xyou should make sure your results do not suffer because the producer
  367. Xsystem cannot run full speed.
  368. X
  369. XI suggest you check out the lines with "cu" before you start testing
  370. Xto make sure everything really works.  I can tell you from experience
  371. Xit is frustrating to discover a bad line when the input test is
  372. X3/4 complete.
  373. X
  374. XWith a DigiBoard PC/8e under SCO Xenix, begin the test by typing the
  375. Xfollowing command on the console of the consumer system:
  376. X
  377. X          islave 9600 /dev/ttyi1[a-h] | tee junk
  378. X
  379. XThen go to the console of the producer system and type:
  380. X
  381. X          ibench 9600 exta extb ixoff -icanon /dev/ttyi1[a-h]
  382. X
  383. XThe producer system will begin sending commands and test data to
  384. Xthe consumer system; the consumer system will report test results
  385. Xon the console and in the file "junk".
  386. X
  387. XSince the producer system sends commands as well as test data to
  388. Xthe consumer system, it is essential that communication between the
  389. Xtwo systems remains intact during the test.  Remember that you may
  390. Xbe seriously overloading the input capacity of the consumer system,
  391. Xcausing test commands to be lost.  If this phenomenon occurs, it
  392. Xmay be necessary to run the tests by hand.
  393. X
  394. XYou should check the output on the consoles of both the producer
  395. Xand consumer systems as the test progresses.  The same number of
  396. Xdisplay lines are written to both terminals in a very similar format,
  397. Xso it is easy to see if there is a problem.
  398. X
  399. XThe output written to the consumer display, and captured in the
  400. Xfile junk should be very similar to the following:
  401. X
  402. XTEST tty=1, baud=9600, mode=-icanon, flow=ixoff
  403. XTIME process=0.0, interrupt=6.5, total=6.5
  404. X/dev/ttyi1a : IN  cps=960, real=104.16, user=0.0, sys=0.0, errs=0, stray=0
  405. XTEST tty=2, baud=9600, mode=-icanon, flow=ixoff
  406. XTIME process=0.0, interrupt=12.4, total=12.4
  407. X/dev/ttyi1e : IN  cps=960, real=104.16, user=0.0, sys=0.0, errs=0, stray=0
  408. X/dev/ttyi1a : IN  cps=960, real=104.16, user=0.0, sys=0.0, errs=0, stray=0
  409. XTEST tty=3, baud=9600, mode=-icanon, flow=ixoff
  410. XTIME process=0.0, interrupt=16.7, total=16.8
  411. X/dev/ttyi1b : IN  cps=960, real=104.16, user=0.0, sys=0.0, errs=0, stray=0
  412. X/dev/ttyi1a : IN  cps=959, real=104.20, user=0.0, sys=0.0, errs=0, stray=0
  413. X/dev/ttyi1e : IN  cps=960, real=104.16, user=0.0, sys=0.0, errs=0, stray=0
  414. XTEST tty=4, baud=9600, mode=-icanon, flow=ixoff
  415. XTIME process=0.0, interrupt=21.7, total=21.7
  416. X/dev/ttyi1e : IN  cps=960, real=104.14, user=0.0, sys=0.0, errs=0, stray=0
  417. X/dev/ttyi1b : IN  cps=959, real=104.18, user=0.0, sys=0.0, errs=0, stray=0
  418. X/dev/ttyi1f : IN  cps=960, real=104.14, user=0.0, sys=0.0, errs=0, stray=0
  419. X/dev/ttyi1a : IN  cps=959, real=104.18, user=0.0, sys=0.0, errs=0, stray=0
  420. XTEST tty=5, baud=9600, mode=-icanon, flow=ixoff
  421. XTIME process=0.1, interrupt=26.5, total=26.6
  422. X/dev/ttyi1a : IN  cps=959, real=104.18, user=0.0, sys=0.0, errs=0, stray=0
  423. X/dev/ttyi1f : IN  cps=960, real=104.14, user=0.0, sys=0.0, errs=0, stray=0
  424. X/dev/ttyi1e : IN  cps=960, real=104.14, user=0.0, sys=0.0, errs=0, stray=0
  425. X/dev/ttyi1b : IN  cps=960, real=104.14, user=0.0, sys=0.0, errs=0, stray=0
  426. X/dev/ttyi1c : IN  cps=959, real=104.18, user=0.0, sys=0.0, errs=0, stray=0
  427. XTEST tty=6, baud=9600, mode=-icanon, flow=ixoff
  428. XTIME process=0.0, interrupt=31.2, total=31.2
  429. X/dev/ttyi1e : IN  cps=960, real=104.16, user=0.0, sys=0.0, errs=0, stray=0
  430. X/dev/ttyi1b : IN  cps=960, real=104.16, user=0.0, sys=0.0, errs=0, stray=0
  431. X/dev/ttyi1f : IN  cps=960, real=104.16, user=0.0, sys=0.0, errs=0, stray=0
  432. X/dev/ttyi1a : IN  cps=960, real=104.16, user=0.0, sys=0.0, errs=0, stray=0
  433. X/dev/ttyi1c : IN  cps=960, real=104.16, user=0.0, sys=0.0, errs=0, stray=0
  434. X/dev/ttyi1g : IN  cps=960, real=104.16, user=0.0, sys=0.0, errs=0, stray=0
  435. XTEST tty=7, baud=9600, mode=-icanon, flow=ixoff
  436. XTIME process=0.1, interrupt=36.1, total=36.1
  437. X/dev/ttyi1b : IN  cps=960, real=104.16, user=0.0, sys=0.0, errs=0, stray=0
  438. X/dev/ttyi1f : IN  cps=960, real=104.16, user=0.0, sys=0.0, errs=0, stray=0
  439. X/dev/ttyi1e : IN  cps=959, real=104.18, user=0.0, sys=0.0, errs=0, stray=0
  440. X/dev/ttyi1a : IN  cps=960, real=104.14, user=0.0, sys=0.0, errs=0, stray=0
  441. X/dev/ttyi1c : IN  cps=960, real=104.14, user=0.0, sys=0.0, errs=0, stray=0
  442. X/dev/ttyi1g : IN  cps=960, real=104.14, user=0.0, sys=0.0, errs=0, stray=0
  443. X/dev/ttyi1d : IN  cps=960, real=104.14, user=0.0, sys=0.0, errs=0, stray=0
  444. XTEST tty=8, baud=9600, mode=-icanon, flow=ixoff
  445. XTIME process=0.2, interrupt=40.1, total=40.3
  446. X/dev/ttyi1b : IN  cps=956, real=104.52, user=0.0, sys=0.0, errs=0, stray=0
  447. X/dev/ttyi1a : IN  cps=956, real=104.52, user=0.0, sys=0.0, errs=0, stray=0
  448. X/dev/ttyi1f : IN  cps=956, real=104.56, user=0.0, sys=0.0, errs=0, stray=0
  449. X/dev/ttyi1e : IN  cps=956, real=104.52, user=0.0, sys=0.0, errs=0, stray=0
  450. X/dev/ttyi1d : IN  cps=956, real=104.52, user=0.0, sys=0.0, errs=0, stray=0
  451. X/dev/ttyi1c : IN  cps=956, real=104.52, user=0.0, sys=0.0, errs=0, stray=0
  452. X/dev/ttyi1g : IN  cps=956, real=104.60, user=0.0, sys=0.1, errs=0, stray=0
  453. X/dev/ttyi1h : IN  cps=956, real=104.60, user=0.0, sys=0.0, errs=0, stray=0
  454. XTEST tty=1, baud=9600, mode=icanon, flow=ixoff
  455. XTIME process=0.0, interrupt=13.4, total=13.4
  456. X/dev/ttyi1a : IN  cps=960, real=104.14, user=0.0, sys=0.0, errs=0, stray=0
  457. XTEST tty=2, baud=9600, mode=icanon, flow=ixoff
  458. XTIME process=0.0, interrupt=24.4, total=24.5
  459. X/dev/ttyi1e : IN  cps=960, real=104.16, user=0.0, sys=0.0, errs=0, stray=0
  460. X/dev/ttyi1a : IN  cps=960, real=104.16, user=0.0, sys=0.0, errs=0, stray=0
  461. XTEST tty=3, baud=9600, mode=icanon, flow=ixoff
  462. XTIME process=12.6, interrupt=22.6, total=35.2
  463. X              ...
  464. X
  465. XNote that both the "errs" and "stray" counts should ideally be zero
  466. Xduring this test until the consumer system becomes overloaded.
  467. XEach system is different, but it is usually easy to see when things
  468. Xare beginning to go wrong.
  469. X
  470. XWhen the test is complete, you should then run iprint to format
  471. Xthe input results you got above.  Type the following command on
  472. Xthe consumer system:
  473. X
  474. X          iprint junk
  475. X
  476. XThis action will produce a report similar to the following:
  477. X
  478. X ports     baud      mode     flow      cps      errs      %sys      %host
  479. X -----    ------    ------   ------    -----    ------    -------   ------
  480. X
  481. X    1     19200    -icanon    ixoff   1920.0      0.0       8.51     4.43
  482. X    2     19200    -icanon    ixoff   1913.0      0.0      14.03     3.67
  483. X    3     19200    -icanon    ixoff   1919.0      0.0      20.44     3.55
  484. X    4     19200    -icanon    ixoff   1919.3      0.0      26.65     3.47
  485. X    5     19200    -icanon    ixoff   1919.8      0.0      33.17     3.46
  486. X    6     19200    -icanon    ixoff   1919.5      0.0      38.88     3.38
  487. X    7     19200    -icanon    ixoff   1919.4      0.0      44.79     3.33
  488. X    8     19200    -icanon    ixoff   1919.1      0.0      49.69     3.37
  489. X    9     19200    -icanon    ixoff   1919.6      0.0      57.42     3.32
  490. X   10     19200    -icanon    ixoff   1919.2      0.0      63.54     3.31
  491. X   11     19200    -icanon    ixoff   1919.6      0.0      69.85     3.31
  492. X   12     19200    -icanon    ixoff   1919.0      0.0      75.96     3.30
  493. X   13     19200    -icanon    ixoff   1919.5      0.0      81.57     3.27
  494. X   14     19200    -icanon    ixoff   1918.3      0.0      83.60     3.11
  495. X   15     19200    -icanon    ixoff   1872.4      0.0      83.60     2.98
  496. X   16     19200    -icanon    ixoff   1828.6      0.0      83.24     2.84
  497. X
  498. X    1     38400    -icanon    ixoff   3839.0      0.0      12.03     3.13
  499. X    2     38400    -icanon    ixoff   3840.0      0.0      21.45     2.79
  500. X    3     38400    -icanon    ixoff   3839.7      0.0      31.28     2.72
  501. X    4     38400    -icanon    ixoff   3838.8      0.0      41.11     2.68
  502. X    5     38400    -icanon    ixoff   3839.6      0.0      50.43     2.63
  503. X                             ...
  504. X
  505. XThe columns printed are:
  506. X
  507. Xbaud    The test baud rate.
  508. X
  509. Xmode    The communication mode, either icanon (cooked) or -icanon
  510. X    (raw).
  511. X
  512. Xflow    The flow control mode, either ixoff (input flow control)
  513. X    -ixoff (no flow control).
  514. X
  515. Xcps    The character per second (cps) input speed actually measured.
  516. X    Under ideal conditions, this will be the baud rate divided
  517. X    by 10.  Lower numbers indicate a reduction in performance.
  518. X    Higher numbers indicate the consumer system clock is running
  519. X    slow during the test; check with a stopwatch.
  520. X
  521. Xerrors    Number of 6 digit + checksum codes missing from the input
  522. X    stream.  When this number goes non-zero, you may assume you
  523. X    have begun to overload the producer system.
  524. X
  525. X%sys    Percent of system time used during the steady-state portion of
  526. X    the test.  This is computed by starting with 100%, subtracting
  527. X    the "perf" program user time, and the idle time measured by
  528. X    the "cpu" program.   Because it is a subtractive method, it
  529. X    is less accurate at lower loads, and progressively more
  530. X    accurate as the load increases.
  531. X
  532. X%host    Percent of system time used per kilo-character of input
  533. X    data received.
  534. X
  535. XIf there are any obvious inconsistencies in the input,  iprint will
  536. Xinsert an error line to let you know.  You may wish to just edit out
  537. Xthe input data in error, and replace it with corresponding comment
  538. Xlines explaining the problem.
  539. X
  540. XIf you wish, you may edit comment lines into your raw data files
  541. Xto identify details of the test, and problems you encountered.
  542. XSuch comments lines must contain a pound sign (#) in column 1.
  543. XComments are passed transparently through both oprint and iprint.
  544. END_OF_README
  545. if test 23749 -ne `wc -c <README`; then
  546.     echo shar: \"README\" unpacked with wrong size!
  547. fi
  548. # end of overwriting check
  549. fi
  550. if test -f cpu.c -a "${1}" != "-c" ; then 
  551.   echo shar: Will not over-write existing file \"cpu.c\"
  552. else
  553. echo shar: Extracting \"cpu.c\" \(7481 characters\)
  554. sed "s/^X//" >cpu.c <<'END_OF_cpu.c'
  555. X/*     :ex:se ts=4 sw=4    This program formatted with tabs 4 */
  556. X
  557. X/****************************************************
  558. X *     This software released to the public domain  *
  559. X *     without restrictions of any kind.            *
  560. X ****************************************************/
  561. X
  562. X/*
  563. X *    NAME
  564. X *        cpu - CPU activity sensor
  565. X *
  566. X *    SYNOPSIS
  567. X *        cpu [ -cdr ] [-s delay ] [ -t time ]
  568. X *
  569. X *    DESCRIPTION
  570. X *        CPU is a program to detect the overall processor
  571. X *        activity present in a system as part of performance
  572. X *        testing.  CPU must be calibrated on an idle
  573. X *        system, where it times a test loop and writes
  574. X *        the results to the file /tmp/.cpu.   Thereafter
  575. X *        CPU may be run at any time when the system is
  576. X *        under load.   Using CPU statistics provided by
  577. X *        the system, and by measuring the test loop slowdown,
  578. X *        the program can approximate general system CPU loading.
  579. X *
  580. X *        -c            Calibrate.  Should be run when the system
  581. X *                    is as idle as possible; single user mode
  582. X *                    is best.
  583. X *
  584. X *        -d            Turn on debugging flags.
  585. X *
  586. X *        -r            Test repeatedly until interrupted.
  587. X *
  588. X *        -s delay    Sleep for the given delay time before
  589. X *                    beginning the test.
  590. X *
  591. X *        -t time        Run the test for time seconds.
  592. X *                
  593. X *        On completion, CPU outputs the following 3 time values.
  594. X *
  595. X *        process        The amount of time the system reported
  596. X *                    that other processes were running.
  597. X *
  598. X *        interrupt    The slowdown of the test loop not reflected
  599. X *                    by the system statistics.  Most likely this
  600. X *                    time was consumed by interrupt routines, by
  601. X *                    task switching overhead, or because activity
  602. X *                    was synchronized to the system clock.
  603. X *
  604. X *        total        The total slowdown of the test loop relative
  605. X *                    to the speed measured at calibration time.
  606. X *
  607. X *        The total time is the most interesting, since it reflects
  608. X *        the real processor utilization abosorbed by other processes.
  609. X *        Proper use of the other two numbers is left as a problem
  610. X *        for the reader.
  611. X *
  612. X *    WARNINGS
  613. X *        CPU is astoundingly inaccurate in systems with different
  614. X *        speed memories.  In some systems (eg i386 with 16 bit
  615. X *        memory on the AT bus) it is not uncommon for calibration
  616. X *        runs to vary by a factor of 2 or more.  There is no
  617. X *        solution but to change the memory or find another machine.
  618. X *
  619. X *        The order of parameters 2 & 3 on setvbuf() vary from
  620. X *        system, and are even inconsistent between the manuals
  621. X *        and the libraries on stock system V.2.  You are wise
  622. X *        to check the order of the parameters on your system and
  623. X *        set the SETVBUF #define accordingly.
  624. X */
  625. X
  626. X#if !defined(lint)
  627. Xchar whatstring[] = "@(#)cpu.c    3.1 9/22/89" ;
  628. X#endif
  629. X
  630. X#if sun
  631. X#define BSD 1
  632. X#endif
  633. X
  634. X#if BSD
  635. X#    include <sys/types.h>
  636. X#    include <sys/time.h>
  637. X#    include <sys/resource.h>
  638. X#else
  639. X#    include <sys/types.h>
  640. X#    include <sys/times.h>
  641. X#    include <sys/param.h>
  642. X#endif
  643. X
  644. X#include <signal.h>
  645. X#include <ctype.h>
  646. X#include <stdio.h>
  647. X
  648. X#define uchar unsigned char
  649. X#define ushort unsigned short
  650. X#define ulong unsigned long
  651. X
  652. Xextern char *optarg ;
  653. Xextern int optind ;
  654. X
  655. Xextern char *ttyname() ;
  656. Xextern long atol() ;
  657. Xextern void (*signal())() ;
  658. Xextern unsigned sleep() ;
  659. X
  660. X#if BSD
  661. X#else
  662. Xextern unsigned alarm() ;
  663. Xextern void exit() ;
  664. Xextern void perror() ;
  665. Xextern time_t times() ;
  666. X#endif
  667. X
  668. X
  669. X#if BSD
  670. X#    define TICS 1000        /* Fractional seconds */
  671. X#    define MS(tv) (1000000L / TICS * (tv).tv_sec + (tv).tv_usec / TICS)
  672. X#else
  673. X#    define TICS HZ
  674. X#endif
  675. X
  676. X#define CALFILE "/tmp/.cpu"
  677. X
  678. X
  679. Xdouble speed ;                /* Speed of the processor running */
  680. Xdouble process ;            /* Amount of the machine allocated to us */
  681. X
  682. Xint debug ;                    /* Debug flag */
  683. Xint delay ;                    /* Delay before start */
  684. Xint timeout ;                /* Alarm occurred flag */
  685. Xint interrupt ;                /* Got an interrupt */
  686. X
  687. Xulong rep ;                    /* Repeat count */
  688. X
  689. X
  690. X
  691. X/*******
  692. X *    Catch interrupts.
  693. X */
  694. X
  695. Xsigalrm()
  696. X{
  697. X    timeout = 1 ;
  698. X}
  699. X
  700. Xsigint()
  701. X{
  702. X    interrupt = 1 ;
  703. X}
  704. X
  705. X
  706. X/*******
  707. X *    delay - Routine to chew time.
  708. X */
  709. X
  710. Xhog()
  711. X{
  712. X    static int a = 1 ;
  713. X    static int b = 2 ;
  714. X    static int c = 3 ;
  715. X
  716. X    a += b ;
  717. X    b += c ;
  718. X    c += a ;
  719. X}
  720. X
  721. X
  722. X/*******
  723. X *    measure - Procedure to measure our access to the CPU.
  724. X */
  725. X
  726. Xmeasure(runtime)
  727. Xint runtime ;                    /* Time period */
  728. X{
  729. X    ulong real ;
  730. X    ulong sys ;
  731. X    ulong user ;
  732. X    ulong count ;
  733. X
  734. X#if BSD
  735. X    struct timeval tv ;
  736. X    struct rusage ru ;
  737. X#else
  738. X    struct tms tms ;
  739. X#endif
  740. X
  741. X    /*
  742. X     *    Get real time and system time.
  743. X     */
  744. X
  745. X#if BSD
  746. X    (void) gettimeofday(&tv, (struct timezone *)0) ;
  747. X    real = MS(tv) ;
  748. X
  749. X    (void) getrusage(RUSAGE_SELF, &ru) ;
  750. X    user = MS(ru.ru_utime) ;
  751. X    sys = MS(ru.ru_stime) ;
  752. X#else
  753. X    real = times(&tms) ;
  754. X    user = tms.tms_utime ;
  755. X    sys = tms.tms_stime ;
  756. X#endif
  757. X
  758. X    if (debug) (void) fprintf(stderr,"Cpu started\n") ;
  759. X
  760. X    timeout = 0 ;
  761. X    count = 0 ;
  762. X
  763. X    (void) signal(SIGALRM, sigalrm) ;
  764. X    (void) alarm((unsigned) runtime) ;
  765. X
  766. X    (void) nice(40) ;
  767. X
  768. X    while (!timeout && !interrupt)
  769. X    {
  770. X        hog() ;
  771. X        count++ ;
  772. X    }
  773. X
  774. X    (void) nice(-40) ;
  775. X
  776. X#if BSD
  777. X    (void) gettimeofday(&tv, (struct timezone *)0) ;
  778. X    real = MS(tv) - real ;
  779. X
  780. X    (void) getrusage(RUSAGE_SELF, &ru) ;
  781. X    user = MS(ru.ru_utime) - user ;
  782. X    sys = MS(ru.ru_stime) - sys ;
  783. X#else
  784. X    real = times(&tms) - real ;
  785. X    user = tms.tms_utime - user ;
  786. X    sys = tms.tms_stime - sys ;
  787. X#endif
  788. X
  789. X    process = (double) user / (double) real ;
  790. X    speed = user ? (double) count / (double) user : 0.0 ;
  791. X
  792. X    if (debug)
  793. X    {
  794. X        (void) fprintf(stderr,
  795. X            "real=%ld, sys=%ld, user=%ld, count=%ld\n",
  796. X            real, sys, user, count) ;
  797. X        (void) fprintf(stderr, "raw process=%.5f, speed=%.5f\n",
  798. X            process, speed) ;
  799. X    }
  800. X}
  801. X
  802. X
  803. X
  804. Xmain(argc, argv)
  805. Xint argc ;
  806. Xchar **argv ;
  807. X{
  808. X    double cprocess ;
  809. X    double cspeed ;
  810. X    int calibrate ;
  811. X    int runtime = 30 ;
  812. X    int err ;
  813. X    int c ;
  814. X    FILE *cfile ;
  815. X    char iobuf[1024] ;
  816. X    char buf[200] ;
  817. X
  818. X#if SETVBUF
  819. X    (void) setvbuf(stderr, _IOLBF, iobuf, sizeof(iobuf)) ;
  820. X#else
  821. X    (void) setvbuf(stderr, iobuf, _IOLBF, sizeof(iobuf)) ;
  822. X#endif
  823. X
  824. X    (void) nice(-40) ;
  825. X
  826. X    calibrate = 0 ;
  827. X    err = 0 ;
  828. X
  829. X    while ((c = getopt(argc, argv, "cdrs:t:")) != -1)
  830. X    {
  831. X        switch (c)
  832. X        {
  833. X        case 'c':
  834. X            calibrate++ ;
  835. X            break ;
  836. X        
  837. X        case 'd':
  838. X            debug++ ;
  839. X            break ;
  840. X        
  841. X        case 'r':
  842. X            rep = -1 ;
  843. X            break ;
  844. X        
  845. X        case 's':
  846. X            delay = atoi(optarg) ;
  847. X            break ;
  848. X
  849. X        case 't':
  850. X            runtime = atoi(optarg) ;
  851. X            break ;
  852. X        
  853. X        case '?':
  854. X            err++ ;
  855. X        }
  856. X    }
  857. X
  858. X    if (err || optind < argc)
  859. X    {
  860. X        (void) fprintf(stderr,
  861. X            "usage: %s [ -cd ] [ -t time ]\n", argv[0]) ;
  862. X        exit(2) ;
  863. X    }
  864. X
  865. X    if (delay) (void) sleep((unsigned) delay) ;
  866. X
  867. X    if (calibrate)
  868. X    {
  869. X        measure(runtime) ;
  870. X
  871. X        if ((cfile = fopen(CALFILE, "w")) == 0)
  872. X        {
  873. X            perror(CALFILE) ;
  874. X            exit(1) ;
  875. X        }
  876. X
  877. X        (void) fprintf(cfile, "%f %f\n", process, speed) ;
  878. X
  879. X        (void) fprintf(stderr,
  880. X            "Calibrated process=%f, speed=%f\n", process, speed) ;
  881. X    }
  882. X    else
  883. X    {
  884. X        if ((cfile = fopen(CALFILE, "r")) == 0)
  885. X        {
  886. X            perror(CALFILE) ;
  887. X            (void) fprintf(stderr,
  888. X                "Perhaps you should run \"%s -c\" first.\n", argv[0]) ;
  889. X            exit(1) ;
  890. X        }
  891. X
  892. X        if    (    fscanf(cfile, "%lf %lf", &cprocess, &cspeed) != 2
  893. X            ||    cprocess == 0
  894. X            ||    cspeed == 0
  895. X            )
  896. X        {
  897. X            (void) fprintf(stderr,
  898. X                "%s file does not contain calibrated speed.\n", CALFILE) ;
  899. X        }
  900. X
  901. X        if (signal(SIGINT, SIG_IGN) != SIG_IGN)
  902. X            (void) signal(SIGINT, sigint) ;
  903. X
  904. X        for (;;)
  905. X        {
  906. X            measure(runtime) ;
  907. X
  908. X#if 0
  909. X            process /= cprocess ;
  910. X#endif
  911. X            speed /= cspeed ;
  912. X
  913. X            if (debug)
  914. X            {
  915. X                (void) fprintf(stderr, "normalized process=%.5f, speed=%.5f\n",
  916. X                    process, speed) ;
  917. X            }
  918. X
  919. X            (void) sprintf(buf,
  920. X                "TIME process=%.1f, interrupt=%.1f, total=%.1f\n",
  921. X                100 * (1 - process) * speed,
  922. X                100 * (1 - speed),
  923. X                100 * (1 - process * speed)) ;
  924. X
  925. X            (void) write(2, buf, (unsigned) strlen(buf)) ;
  926. X            
  927. X            if (rep == 0 || interrupt) break ;
  928. X
  929. X            rep-- ;
  930. X        }
  931. X    }
  932. X
  933. X    return(0) ;
  934. X}
  935. END_OF_cpu.c
  936. if test 7481 -ne `wc -c <cpu.c`; then
  937.     echo shar: \"cpu.c\" unpacked with wrong size!
  938. fi
  939. # end of overwriting check
  940. fi
  941. if test -f ibench -a "${1}" != "-c" ; then 
  942.   echo shar: Will not over-write existing file \"ibench\"
  943. else
  944. echo shar: Extracting \"ibench\" \(1959 characters\)
  945. sed "s/^X//" >ibench <<'END_OF_ibench'
  946. X#!/bin/sh
  947. X#
  948. X####################################################
  949. X#     This software released to the public domain  #
  950. X#     without restrictions of any kind.            #
  951. X####################################################
  952. X#
  953. X#    @(#)ibench    3.1 9/22/89
  954. X
  955. Xdef_baud="9600 exta extb"
  956. Xdef_flow="ixoff"
  957. Xdef_mode="-icanon"
  958. X
  959. Xtty=
  960. Xbaud=
  961. Xmode=
  962. Xlen=
  963. Xmin=0
  964. X
  965. Xwhile [ "$1" ]
  966. Xdo
  967. X    case "$1" in
  968. X
  969. X    50|75|110|1200|2400|4800|9600|19200|38400|exta|extb)
  970. X        def_baud=
  971. X        baud="$baud $1"
  972. X        ;;
  973. X
  974. X    [1-9]|1[0-6])
  975. X        min=$1
  976. X        ;;
  977. X
  978. X    19200,exta|38400,extb|exta,19200|extb,38400)
  979. X        def_baud=
  980. X        baud="$baud $1"
  981. X        ;;
  982. X    
  983. X    ixoff|-ixoff)
  984. X        def_flow=
  985. X        flow="$flow $1"
  986. X        ;;
  987. X
  988. X    icanon|-icanon)
  989. X        def_mode=
  990. X        mode="$mode $1"
  991. X        ;;
  992. X    
  993. X    /dev/*)
  994. X        tty="$tty $1"
  995. X        ;;
  996. X
  997. X    tty*|cu*)
  998. X        tty="$tty /dev/$1"
  999. X        ;;
  1000. X    
  1001. X    *)
  1002. X        tty="$tty /dev/tty$1"
  1003. X        ;;
  1004. X    esac
  1005. X
  1006. X    shift
  1007. Xdone
  1008. X
  1009. Xbaud="$def_baud $baud"
  1010. Xmode="$def_mode $mode"
  1011. Xflow="$def_flow $flow"
  1012. X
  1013. Xctty=`expr "$tty" : ' *\([^ ]*\)'`
  1014. X
  1015. Xlastb=0
  1016. Xfor b in $baud
  1017. Xdo
  1018. X    b1=`expr "$b" : '\(.*\),.*' \| "$b"` ;
  1019. X    b2=`expr "$b" : '.*,\(.*\)' \| "$b"` ;
  1020. X
  1021. X    if [ $lastb != 0 -a $b1 != $lastb ]
  1022. X    then
  1023. X        for i in $tty
  1024. X        do
  1025. X            (
  1026. X            stty $lastb -echo -icanon -opost
  1027. X            perf -c "stty $b2"
  1028. X            sleep 5
  1029. X            ) <$i >$i &
  1030. X        done
  1031. X        wait
  1032. X    fi
  1033. X    lastb=$b1
  1034. X
  1035. X    case $b1 in
  1036. X    50) vol=574000 ;;
  1037. X    75) vol=768000 ;;
  1038. X    110) vol=1152000 ;;
  1039. X    1200) vol=12000 ;;
  1040. X    2400) vol=24000 ;;
  1041. X    4800) vol=48000 ;;
  1042. X    9600) vol=96000 ;;
  1043. X    exta|19200) vol=192000 ;;
  1044. X    extb|38400) vol=384000 ;;
  1045. X    esac
  1046. X
  1047. X
  1048. X    for f in $flow
  1049. X    do
  1050. X        for m in $mode
  1051. X        do
  1052. X            t=
  1053. X            n=0
  1054. X
  1055. X            for i in $tty
  1056. X            do
  1057. X                t="$t $i"
  1058. X                n=`expr $n + 1`
  1059. X
  1060. X                [ $n -ge $min ] || continue
  1061. X
  1062. X                msg="tty=$n, baud=$b1, mode=$m, flow=$f"
  1063. X                echo "SEND $msg"
  1064. X
  1065. X                (
  1066. X                stty $b1 -echo -opost -icanon
  1067. X                perf -e "TEST $msg"
  1068. X                perf -c "(sleep 30 ; cpu -t 50)&"
  1069. X                ) <$ctty >$ctty
  1070. X
  1071. X                for j in $t
  1072. X                do
  1073. X                    (
  1074. X                    stty $b1 -opost -echo -icanon ixon
  1075. X                    perf -c "stty $m $f"
  1076. X                    sleep 5
  1077. X                    perf $vol
  1078. X                    ) <$j >$j &
  1079. X                done
  1080. X
  1081. X                wait
  1082. X                sleep 10
  1083. X            done
  1084. X        done
  1085. X    done
  1086. Xdone 2>&1
  1087. END_OF_ibench
  1088. if test 1959 -ne `wc -c <ibench`; then
  1089.     echo shar: \"ibench\" unpacked with wrong size!
  1090. fi
  1091. # end of overwriting check
  1092. fi
  1093. if test -f iprint -a "${1}" != "-c" ; then 
  1094.   echo shar: Will not over-write existing file \"iprint\"
  1095. else
  1096. echo shar: Extracting \"iprint\" \(2150 characters\)
  1097. sed "s/^X//" >iprint <<'END_OF_iprint'
  1098. X#!/bin/sh
  1099. X#
  1100. X####################################################
  1101. X#     This software released to the public domain  #
  1102. X#     without restrictions of any kind.            #
  1103. X####################################################
  1104. X#
  1105. X#    @(#)iprint    3.1 9/22/89
  1106. X
  1107. X(    sed -ne '
  1108. X        /^#/p
  1109. X        s/exta/19200/
  1110. X        s/extb/38400/
  1111. X        s/.*TEST.*tty=\([^,]*\).*baud=\([^,]*\).*mode=\([^,]*\).*flow=\([^,]*\).*/TEST \1 \2 \3 \4/p
  1112. X        s/.*TIME.*process=\([^,]*\).*interrupt=\([^,]*\).*total=\([^,]*\).*/TIME \1 \2 \3/p
  1113. X        s/.*INPUT.*IN.*cps=\([^,]*\).*real=\([^,]*\).*user=\([^,]*\).*sys=\([^,]*\).*errs=\([^,]*\).*stray=\([^,]*\).*/CAL \1 \2 \3 \4 \5 \6/p
  1114. X        s/.*dev.*IN.*cps=\([^,]*\).*real=\([^,]*\).*user=\([^,]*\).*sys=\([^,]*\).*errs=\([^,]*\).*stray=\([^,]*\).*/IN \1 \2 \3 \4 \5 \6/p
  1115. X        ' $* \
  1116. X|    awk '
  1117. X        BEGIN {
  1118. X            tty = 0 ; n = 0 ;
  1119. X            cps = 0 ; ; errs = 0 ; stray = 0 ;
  1120. X            process = 0 ; interrupt = 0 ; total = 0 ;
  1121. X            usercost = 48.2 / 85499 ;
  1122. X        }
  1123. X
  1124. X        /^#/ { print ; next }
  1125. X
  1126. X        /^TIME/ {
  1127. X            process += $2 ; interrupt += $3 ; total += $4 ;
  1128. X        }
  1129. X
  1130. X        /^CAL/ {
  1131. X            usercost = $4 / $2 ;
  1132. X        }
  1133. X
  1134. X        /^IN/ {
  1135. X            n += 1 ;
  1136. X            cps += $2 ; errs += $6 ; stray += $7 ;
  1137. X        }
  1138. X
  1139. X        /^TEST/ {
  1140. X            if (n != 0) {
  1141. X                if (n != tty) {
  1142. X                    print "**** Following results suspect:" ;
  1143. X                }
  1144. X
  1145. X                cpu = total - cps * usercost ;
  1146. X                printf("%5d %9s %10s %8s %8.1f %8.1f %10.2f %8.2f\n", \
  1147. X                    tty, baud, mode, flow, cps/n, errs, \
  1148. X                    cpu, 1000*cpu/cps) ;
  1149. X            }
  1150. X
  1151. X            n = 0 ;
  1152. X            cps = 0 ; errs = 0 ; stray = 0 ;
  1153. X            process = 0 ; interrupt = 0 ; total = 0 ;
  1154. X
  1155. X            if (tty == 0) {
  1156. X                printf("\n\n") ;
  1157. X                printf(" ports     baud      mode     flow      cps      errs      %%sys      %%host\n") ;
  1158. X                printf(" -----    ------    ------   ------    -----    ------    -------   ------\n") ;
  1159. X            }
  1160. X
  1161. X            lastbaud = baud ; lastmode = mode ; lastflow = flow ;
  1162. X            tty = $2 ; baud = $3 ; mode = $4 ; flow = $5 ;
  1163. X
  1164. X            if    (baud != lastbaud || lastmode != mode || lastflow != flow) {
  1165. X                printf("\n") ;
  1166. X            }
  1167. X        }
  1168. X
  1169. X        /^\#/ { print }
  1170. X
  1171. X        END {
  1172. X            if (n != 0) {
  1173. X                cpu = total - cps * usercost ;
  1174. X                printf("%5d %9s %10s %8s %8.1f %8.1f %10.2f %8.2f\n", \
  1175. X                    tty, baud, mode, flow, cps/n, errs, \
  1176. X                    cpu, 1000*cpu/cps) ;
  1177. X            }
  1178. X        }
  1179. X        '
  1180. X)
  1181. END_OF_iprint
  1182. if test 2150 -ne `wc -c <iprint`; then
  1183.     echo shar: \"iprint\" unpacked with wrong size!
  1184. fi
  1185. # end of overwriting check
  1186. fi
  1187. if test -f islave -a "${1}" != "-c" ; then 
  1188.   echo shar: Will not over-write existing file \"islave\"
  1189. else
  1190. echo shar: Extracting \"islave\" \(737 characters\)
  1191. sed "s/^X//" >islave <<'END_OF_islave'
  1192. X#!/bin/sh
  1193. X#
  1194. X####################################################
  1195. X#     This software released to the public domain  #
  1196. X#     without restrictions of any kind.            #
  1197. X####################################################
  1198. X#
  1199. X#    @(#)islave    3.2 9/22/89
  1200. X
  1201. Xbaud="9600"
  1202. Xtty=
  1203. X
  1204. Xwhile [ "$1" ]
  1205. Xdo
  1206. X    case "$1" in
  1207. X
  1208. X    50|75|110|1200|2400|4800|9600|19200|38400|exta|extb)
  1209. X        baud="$1"
  1210. X        ;;
  1211. X    
  1212. X    /dev/*)
  1213. X        def_tty=
  1214. X        tty="$tty $1"
  1215. X        ;;
  1216. X
  1217. X    tty*|cu*)
  1218. X        tty="$tty /dev/$1"
  1219. X        ;;
  1220. X    
  1221. X    *)
  1222. X        tty="$tty /dev/tty$1"
  1223. X        ;;
  1224. X    esac
  1225. X
  1226. X    shift
  1227. Xdone
  1228. X
  1229. Xperf 999999 2>/dev/null | perf -s 2>&1
  1230. X
  1231. Xfor i in $tty
  1232. Xdo
  1233. X    (
  1234. X    stty $baud eof '^a' erase '^h' kill '^u' \
  1235. X        cs7 parenb -parodd -icrnl -istrip -ignpar inpck \
  1236. X        -icanon -ixon -ixoff -echo -opost
  1237. X    perf
  1238. X    ) >$i <$i &
  1239. Xdone 2>&1
  1240. X
  1241. Xwait
  1242. END_OF_islave
  1243. if test 737 -ne `wc -c <islave`; then
  1244.     echo shar: \"islave\" unpacked with wrong size!
  1245. fi
  1246. # end of overwriting check
  1247. fi
  1248. if test -f obench -a "${1}" != "-c" ; then 
  1249.   echo shar: Will not over-write existing file \"obench\"
  1250. else
  1251. echo shar: Extracting \"obench\" \(1296 characters\)
  1252. sed "s/^X//" >obench <<'END_OF_obench'
  1253. X#!/bin/sh
  1254. X#
  1255. X####################################################
  1256. X#     This software released to the public domain  #
  1257. X#     without restrictions of any kind.            #
  1258. X####################################################
  1259. X#
  1260. X#    @(#)obench    3.3 10/25/89
  1261. X
  1262. Xdef_baud="9600 exta extb"
  1263. Xdef_mode="opost -opost"
  1264. X
  1265. Xtty=
  1266. Xbaud=
  1267. Xmode=
  1268. Xlen=
  1269. Xmin=0
  1270. X
  1271. Xwhile [ "$1" ]
  1272. Xdo
  1273. X    case "$1" in
  1274. X
  1275. X    50|75|110|1200|2400|4800|9600|19200|38400|exta|extb)
  1276. X        def_baud=
  1277. X        baud="$baud $1"
  1278. X        ;;
  1279. X    
  1280. X    [1-9]|1[0-6])
  1281. X        min=$1
  1282. X        ;;
  1283. X
  1284. X    opost|-opost)
  1285. X        def_mode=
  1286. X        mode="$mode $1"
  1287. X        ;;
  1288. X    
  1289. X    /dev/*)
  1290. X        tty="$tty $1"
  1291. X        ;;
  1292. X
  1293. X    tty*|cu*)
  1294. X        tty="$tty /dev/$1"
  1295. X        ;;
  1296. X    
  1297. X    *)
  1298. X        tty="$tty /dev/tty$1"
  1299. X        ;;
  1300. X    esac
  1301. X
  1302. X    shift
  1303. Xdone
  1304. X
  1305. Xbaud="$def_baud $baud"
  1306. Xmode="$def_mode $mode"
  1307. X
  1308. X(perf -s 999999 >/dev/null) 2>&1
  1309. X
  1310. Xfor b in $baud
  1311. Xdo
  1312. X    case $b in
  1313. X    50) vol=574000 ;;
  1314. X    75) vol=768000 ;;
  1315. X    110) vol=1152000 ;;
  1316. X    1200) vol=12000 ;;
  1317. X    2400) vol=24000 ;;
  1318. X    4800) vol=48000 ;;
  1319. X    9600) vol=96000 ;;
  1320. X    exta|19200) vol=192000 ;;
  1321. X    extb|38400) vol=384000 ;;
  1322. X    esac
  1323. X
  1324. X    for m in $mode
  1325. X    do
  1326. X        t=
  1327. X        n=0
  1328. X
  1329. X        for i in $tty
  1330. X        do
  1331. X            t="$t $i"
  1332. X            n=`expr $n + 1`
  1333. X
  1334. X            [ $n -ge $min ] || continue
  1335. X
  1336. X            echo "TEST tty=$n, baud=$b, mode=$m"
  1337. X
  1338. X            for j in $t
  1339. X            do
  1340. X                (
  1341. X                stty $b $m -ixon -ixoff
  1342. X                sleep 10
  1343. X                perf $vol
  1344. X                ) >$j <&1 &
  1345. X            done
  1346. X
  1347. X            sleep 30
  1348. X            cpu -t 50
  1349. X
  1350. X            wait
  1351. X        done
  1352. X    done
  1353. Xdone 2>&1
  1354. END_OF_obench
  1355. if test 1296 -ne `wc -c <obench`; then
  1356.     echo shar: \"obench\" unpacked with wrong size!
  1357. fi
  1358. # end of overwriting check
  1359. fi
  1360. if test -f oprint -a "${1}" != "-c" ; then 
  1361.   echo shar: Will not over-write existing file \"oprint\"
  1362. else
  1363. echo shar: Extracting \"oprint\" \(1952 characters\)
  1364. sed "s/^X//" >oprint <<'END_OF_oprint'
  1365. X#!/bin/sh
  1366. X#
  1367. X####################################################
  1368. X#     This software released to the public domain  #
  1369. X#     without restrictions of any kind.            #
  1370. X####################################################
  1371. X#
  1372. X#    @(#)oprint    3.1 9/22/89
  1373. X
  1374. X(    sed -ne '
  1375. X        /^#/p
  1376. X        s/exta/19200/
  1377. X        s/extb/38400/
  1378. X        s/.*TEST.*tty=\([^,]*\).*baud=\([^,]*\).*mode=\([^,]*\).*/TEST \1 \2 \3/p
  1379. X        s/.*OUTPUT.*OUT.*cps=\([^,]*\).*real=\([^,]*\).*user=\([^,]*\).*sys=\([^,]*\).*/CAL \1 \2 \3 \4/p
  1380. X        s/.*dev.*OUT.*cps=\([^,]*\).*real=\([^,]*\).*user=\([^,]*\).*sys=\([^,]*\).*/OUT \1 \2 \3 \4/p
  1381. X        s/.*TIME.*process=\([^,]*\).*interrupt=\([^,]*\).*total=\([^,]*\).*/TIME \1 \2 \3/p
  1382. X        ' $* \
  1383. X|    tee junk \
  1384. X|    awk '
  1385. X        BEGIN {
  1386. X            tty = 0 ; n = 0 ;
  1387. X            process = 0 ; interrupt = 0 ; total = 0 ;
  1388. X            cps = 0 ; real = 0 ;
  1389. X            usercost = 42.2 / 85470 ;
  1390. X        }
  1391. X
  1392. X        /^\#/ { print ; next }
  1393. X
  1394. X        /^TIME/ {
  1395. X            process += $2 ; interrupt += $3 ; total += $4 ;
  1396. X            }
  1397. X
  1398. X        /^CAL/ {
  1399. X            usercost = $4 / $2 ;
  1400. X        }
  1401. X
  1402. X        /^OUT/ {
  1403. X            cps += $2 ; real += $3 ;
  1404. X            n += 1 ;
  1405. X        }
  1406. X
  1407. X        /^TEST/ {
  1408. X            if (tty == 0) {
  1409. X                printf("\n\n") ;
  1410. X                printf(" ports     baud      mode        cps      real      %%sys     %%host\n") ;
  1411. X                printf(" -----    ------    ------      -----    ------    -----     ----\n") ;
  1412. X            }
  1413. X
  1414. X            if (n != 0) {
  1415. X                if (n != tty) {
  1416. X                    print "**** Following results suspect:" ;
  1417. X                }
  1418. X
  1419. X                cpu = total - cps * usercost ;
  1420. X                printf("%5d %9s %10s   %8.1f %9.1f %8.1f %8.2f\n", \
  1421. X                    tty, baud, mode, cps / n, real / n, \
  1422. X                    cpu, 1000 * cpu / cps) ;
  1423. X            }
  1424. X
  1425. X            lastbaud=baud ; lastmode=mode ;
  1426. X            tty = $2 ; baud = $3 ; mode = $4 ;
  1427. X
  1428. X            if (n != 0 && (baud != lastbaud || lastmode != mode)) {
  1429. X                printf("\n") ;
  1430. X            }
  1431. X
  1432. X            n = 0 ;
  1433. X            process = 0 ; interrupt = 0 ; total = 0 ;
  1434. X            cps = 0 ; real = 0 ;
  1435. X        }
  1436. X        END {
  1437. X            if (n != 0) {
  1438. X                cpu = total - cps * usercost ;
  1439. X                printf("%5d %9s %10s   %8.1f %9.1f %8.1f %8.2f\n", \
  1440. X                    tty, baud, mode, cps/n, real/n, \
  1441. X                    cpu, 1000 * cpu / cps) ;
  1442. X            }
  1443. X        }
  1444. X        '
  1445. X)
  1446. END_OF_oprint
  1447. if test 1952 -ne `wc -c <oprint`; then
  1448.     echo shar: \"oprint\" unpacked with wrong size!
  1449. fi
  1450. # end of overwriting check
  1451. fi
  1452. if test -f perf.c -a "${1}" != "-c" ; then 
  1453.   echo shar: Will not over-write existing file \"perf.c\"
  1454. else
  1455. echo shar: Extracting \"perf.c\" \(16238 characters\)
  1456. sed "s/^X//" >perf.c <<'END_OF_perf.c'
  1457. X/*     :ex:se ts=4 sw=4    This program formatted with tabs 4 */
  1458. X
  1459. X/****************************************************
  1460. X *     This software released to the public domain  *
  1461. X *     without restrictions of any kind.            *
  1462. X ****************************************************/
  1463. X
  1464. X/*
  1465. X *    NAME
  1466. X *        perf - Test I/O system PERFormance.
  1467. X *
  1468. X *    SYNOPSIS
  1469. X *        perf [ -qsv ] [ -c command ] [ -e text ]
  1470. X *             [ -t throttle ] [ -x outcount ] [ outcount ... ]
  1471. X *
  1472. X *    DESCRIPTION
  1473. X *        Perf measures the transmission of characters through
  1474. X *        a communication media, keeping statistics on throughput
  1475. X *        and system utilization.
  1476. X *
  1477. X *        When the any of the options c, e, q, t or x, or an
  1478. X *        outcount is specified, the program runs in output mode;
  1479. X *        Otherwise it runs in input mode.  A perf in output mode
  1480. X *        may be used to test a system I/O subsystem output speed
  1481. X *        directly,  or its output may be fed through communication
  1482. X *        hardware back into a perf in input mode for input
  1483. X *        performance testing.
  1484. X *
  1485. X *        -c shell_command    Output the given shell command to be
  1486. X *                            executed by the receiving perf program.
  1487. X *
  1488. X *        -e text                Output the given text to be displayed
  1489. X *                            by the receiving perf program.
  1490. X *
  1491. X *        -q                    Output code 99998, which tells the
  1492. X *                            receiving perf to terminate.
  1493. X *
  1494. X *        -s                    Silent option.  Suppress warning messages.
  1495. X *
  1496. X *        -t throttle            Throttle the input by sleeping for
  1497. X *                            one second every throttle characters.
  1498. X *
  1499. X *        -v                    On input, print statistics showing
  1500. X *                            the length and number of times a
  1501. X *                            stream of characters was missed.
  1502. X *
  1503. X *        -x outchar            Output enough 6 digit + checksum
  1504. X *                            codes to produce the given number of
  1505. X *                            characters.
  1506. X *    
  1507. X *        outcount            Same as -x outcount above.
  1508. X *
  1509. X *        All data sent by an output perf can be interpreted by
  1510. X *        an input perf, but the data is all printable ASCII in
  1511. X *        a simple format so a human can understand it as well.
  1512. X *
  1513. X *        To test system throughput, the perf program uses 6 digit
  1514. X *        sequential codes, with a checksum.  This format allows
  1515. X *        the input program--or a human observer--to easily and
  1516. X *        quantitatively compare    desired to actual data.
  1517. X *
  1518. X *        For input testing, it is often valuable to send data
  1519. X *        from one system to another.  In this mode, perf can
  1520. X *        pass diagnostics text and shell commands through the
  1521. X *        communications link.  This allows the output system
  1522. X *        to control the overall test procedure, and provide a
  1523. X *        test log on the input system.
  1524. X *
  1525. X *        To improve accuracy, on output a code of 99998 is output
  1526. X *        for about 10K characters before measurement begins and
  1527. X *        after measurement completes.  This is done so the
  1528. X *        measurement is more likely to be done under steady-state
  1529. X *        conditions.
  1530. X *
  1531. X *    WARNING
  1532. X *        The order of parameters 2 & 3 on setvbuf() vary from
  1533. X *        system, and are even inconsistent between the manuals
  1534. X *        and the libraries on stock system V.2.  You are wise
  1535. X *        to check the order of the parameters on your system and
  1536. X *        set the SETVBUF #define accordingly.
  1537. X */
  1538. X
  1539. X#if !defined(lint)
  1540. Xchar whatstring[] = "@(#)perf.c    3.1 9/22/89" ;
  1541. X#endif
  1542. X
  1543. X#if sun
  1544. X#define BSD 1
  1545. X#endif
  1546. X
  1547. X#if BSD
  1548. X#    include <sys/types.h>
  1549. X#    include <sys/time.h>
  1550. X#    include <sys/resource.h>
  1551. X#else
  1552. X#    include <sys/types.h>
  1553. X#    include <sys/times.h>
  1554. X#    include <sys/param.h>
  1555. X#endif
  1556. X
  1557. X#include <ctype.h>
  1558. X#include <stdio.h>
  1559. X
  1560. X#define uchar unsigned char
  1561. X#define ushort unsigned short
  1562. X#define ulong unsigned long
  1563. X
  1564. Xextern char *optarg ;
  1565. Xextern int optind ;
  1566. X
  1567. Xextern char *ttyname() ;
  1568. Xextern long atol() ;
  1569. Xextern unsigned sleep() ;
  1570. X
  1571. X#if BSD
  1572. Xextern char *sprintf() ;
  1573. X#else
  1574. Xextern int sprintf() ;
  1575. Xextern void exit() ;
  1576. Xextern time_t times() ;
  1577. X#endif
  1578. X
  1579. X
  1580. X#if BSD
  1581. X#    define TICS 1000        /* Fractional seconds */
  1582. X#    define MS(tv) (1000000L / TICS * (tv).tv_sec + (tv).tv_usec / TICS)
  1583. X#else
  1584. X#    define TICS HZ
  1585. X#endif
  1586. X
  1587. X
  1588. X#define NDIG    6            /* Number of digits/code */
  1589. X#define MAXCODE    999999        /* Largest NDIG number */
  1590. X
  1591. X#define NHEAD    10000        /* Number of header characters */
  1592. X#define NTRAIL    10000        /* Number of trailer characters */
  1593. X
  1594. X#define CPL        9            /* Number of codes per line */
  1595. X#define BASE    0x3f        /* Base character for checksum */
  1596. X
  1597. X#define NCHAR(ncode) ((NDIG + 2) * (ncode) + 2 * (((ncode) + CPL - 1) / CPL))
  1598. X#define NCODE(nchar) (((nchar) * CPL) / (CPL * (NDIG + 2) + 2))
  1599. X
  1600. X
  1601. Xchar iobuf[3][BUFSIZ] ;
  1602. X
  1603. X/*
  1604. X *    Command options.
  1605. X */
  1606. X
  1607. Xint verbose ;                /* Verbose error reporting */
  1608. Xlong throttle ;                /* Max chars between sleep calls */
  1609. Xint silent ;                /* Silent option */
  1610. Xint out ;                    /* Output test */
  1611. X
  1612. X/*
  1613. X *    Misc globals.
  1614. X */
  1615. X
  1616. Xint linepos ;                /* Code position in line */
  1617. Xchar *tname ;                /* Input/output ttyname */
  1618. X
  1619. X/*
  1620. X *    Statistics gathering.
  1621. X */
  1622. X
  1623. X#define MAXSTAT    100            /* Gap max for statistics */
  1624. Xint gap[MAXSTAT] ;            /* Statistics on code gaps */
  1625. X
  1626. X
  1627. X/*************************************************************
  1628. X *     Output a numeric code sequence                        *
  1629. X *************************************************************/
  1630. X
  1631. Xoutcode(v)
  1632. Xregister long v ;
  1633. X{
  1634. X    register int ch ;
  1635. X    register char *p ;
  1636. X    static char digits[NDIG] ;
  1637. X    static long lastv ;
  1638. X
  1639. X    if (v == lastv)
  1640. X    {
  1641. X        p = &digits[NDIG] ;
  1642. X    }
  1643. X    else if (v == lastv + 1)
  1644. X    {
  1645. X        lastv++ ;
  1646. X        for (p = digits ; *p == 9 ;) *p++ = 0 ;
  1647. X        *p += 1 ;
  1648. X        p = &digits[NDIG] ;
  1649. X    }
  1650. X    else
  1651. X    {
  1652. X        lastv = v ;
  1653. X        for (p = digits ; p != &digits[NDIG] ;)
  1654. X        {
  1655. X            *p++ = v % 10 ;
  1656. X            v /= 10 ;
  1657. X        }
  1658. X    }
  1659. X
  1660. X    v = 0 ;
  1661. X    while (p != &digits[0])
  1662. X    {
  1663. X        ch = *--p ;
  1664. X        v += (v << 4) + ch ;
  1665. X        ch += '0' ;
  1666. X        (void) putc(ch, stdout) ;
  1667. X    }
  1668. X
  1669. X    ch = (v & 0x3f) + BASE ;
  1670. X    (void) putc(ch, stdout) ;
  1671. X
  1672. X    ch = ((v >> 6) & 0x3f) + BASE ;
  1673. X    (void) putc(ch, stdout) ;
  1674. X
  1675. X    if (++linepos == CPL)
  1676. X    {
  1677. X        (void) printf("\r\n") ;
  1678. X        linepos = 0 ;
  1679. X    }
  1680. X}
  1681. X
  1682. X
  1683. X
  1684. X/***************************************************************
  1685. X *    Close out the current line                               *
  1686. X ***************************************************************/
  1687. X
  1688. Xcloseline()
  1689. X{
  1690. X    if (linepos)
  1691. X    {
  1692. X        (void) printf("\r\n") ;
  1693. X        linepos = 0 ;
  1694. X    }
  1695. X}
  1696. X
  1697. X
  1698. X
  1699. X/************************************************************
  1700. X *        Send text to a remote                             *
  1701. X ************************************************************/
  1702. X
  1703. Xsendtext(prefix, text)
  1704. Xint prefix ;
  1705. Xchar *text ;
  1706. X{
  1707. X    int ch ;
  1708. X    unsigned check ;
  1709. X
  1710. X    closeline() ;
  1711. X
  1712. X    for (;;)
  1713. X    {
  1714. X        check = 0 ;
  1715. X        (void) fputc(prefix, stdout) ;
  1716. X
  1717. X        while ((ch = *text++) && ch != '\n')
  1718. X        {
  1719. X            (void) fputc(ch, stdout) ;
  1720. X            check = 17 * check + ch ;
  1721. X        }
  1722. X
  1723. X        (void) fputc((int)(check & 0x3f) + BASE, stdout) ;
  1724. X        check >>= 6 ;
  1725. X        (void) fputc((int)(check & 0x3f) + BASE, stdout) ;
  1726. X
  1727. X        (void) printf("\r\n") ;
  1728. X
  1729. X        if (ch == 0) break ;
  1730. X    }
  1731. X}
  1732. X
  1733. X
  1734. X
  1735. X/***************************************************************
  1736. X *    Transmit a given number of output codes                  *
  1737. X ***************************************************************/
  1738. X
  1739. Xtransmit(ncode)
  1740. Xlong ncode ;
  1741. X{
  1742. X    long code ;
  1743. X    ulong real ;
  1744. X    ulong user ;
  1745. X    ulong sys ;
  1746. X    int cps ;
  1747. X    char buf[200] ;
  1748. X
  1749. X#if BSD
  1750. X    struct timeval tv ;
  1751. X    struct rusage ru ;
  1752. X#else
  1753. X    struct tms tms ;
  1754. X#endif
  1755. X
  1756. X    /*
  1757. X     *    Output header codes to fill the output queue so we
  1758. X     *    will get a better idea of the true transmission times.
  1759. X     */
  1760. X
  1761. X    (void) printf("\r\n") ;
  1762. X
  1763. X    linepos = 0 ;
  1764. X    code = NCODE(NHEAD) ;
  1765. X    while (--code >= 0) outcode((long) (MAXCODE - 1)) ;
  1766. X    closeline() ;
  1767. X    (void) fflush(stdout) ;
  1768. X
  1769. X    /*
  1770. X     *    Get time statistics.
  1771. X     */
  1772. X
  1773. X#if BSD
  1774. X    (void) gettimeofday(&tv, (struct timezone *)0) ;
  1775. X    real = MS(tv) ;
  1776. X
  1777. X    (void) getrusage(RUSAGE_SELF, &ru) ;
  1778. X    user = MS(ru.ru_utime) ;
  1779. X    sys = MS(ru.ru_stime) ;
  1780. X#else
  1781. X    real = times(&tms) ;
  1782. X    user = tms.tms_utime ;
  1783. X    sys = tms.tms_stime ;
  1784. X#endif
  1785. X
  1786. X    /*
  1787. X     *    Output ncode actual codes.
  1788. X     */
  1789. X
  1790. X    for (code = 0 ; code < ncode ; code++) outcode(code) ;
  1791. X    closeline() ;
  1792. X    (void) fflush(stdout) ;
  1793. X
  1794. X    /*
  1795. X     *    Figure the system resources used in the
  1796. X     *    duration of the test.
  1797. X     */
  1798. X
  1799. X#if BSD
  1800. X    (void) gettimeofday(&tv, (struct timezone *)0) ;
  1801. X    real = MS(tv) - real ;
  1802. X
  1803. X    (void) getrusage(RUSAGE_SELF, &ru) ;
  1804. X    user = MS(ru.ru_utime) - user ;
  1805. X    sys = MS(ru.ru_stime) - sys ;
  1806. X    cps = 1000L * NCHAR(ncode) / (real ? real : 1) ;
  1807. X#else
  1808. X    real = times(&tms) - real ;
  1809. X    cps = TICS * NCHAR(ncode) / (real ? real : 1) ;
  1810. X    user = tms.tms_utime - user ;
  1811. X    sys = tms.tms_stime - sys ;
  1812. X#endif
  1813. X
  1814. X    if (real == 0) real = 1 ;
  1815. X    
  1816. X    /*
  1817. X     *    Output trailer codes to end the sequence.
  1818. X     */
  1819. X
  1820. X    code = NCODE(NTRAIL) ;
  1821. X    while (--code >= 0) outcode((long) (MAXCODE - 1)) ;
  1822. X    closeline() ;
  1823. X
  1824. X    (void) fflush(stdout) ;
  1825. X
  1826. X    /*
  1827. X     *    Output results.
  1828. X     */
  1829. X
  1830. X    (void) sprintf(buf,
  1831. X        "%s : OUT cps=%ld, real=%.2f, user=%.1f, sys=%.1f\n",
  1832. X        tname, cps, (double) real / TICS,
  1833. X        100.0 * (double) user / (double) real,
  1834. X        100.0 * (double) sys / (double) real) ;
  1835. X
  1836. X    (void) write(2, buf, (unsigned) strlen(buf)) ;
  1837. X}
  1838. X
  1839. X
  1840. X/***********************************************************
  1841. X *    Honor a text escape from the remote.                 *
  1842. X ***********************************************************/
  1843. X
  1844. Xreadtext(prefix)
  1845. Xint prefix ;
  1846. X{
  1847. X    int ch ;
  1848. X    int n ;
  1849. X    int i ;
  1850. X    int check ;
  1851. X    char buf[1000] ;
  1852. X
  1853. X    n = 0 ;
  1854. X
  1855. X    for (;;)
  1856. X    {
  1857. X        if ((ch = fgetc(stdin)) == EOF) break ;
  1858. X        ch &= 0x7f ;
  1859. X
  1860. X        if (ch == '\r' || ch == '\n') break ;
  1861. X
  1862. X        if (n < sizeof(buf))
  1863. X        {
  1864. X            buf[n] = ch ;
  1865. X        }
  1866. X        n++ ;
  1867. X    }
  1868. X
  1869. X    if (n < 2 || n > sizeof(buf))
  1870. X    {
  1871. X        (void) fprintf(stderr, "Text size error!\n", prefix) ;
  1872. X        return ;
  1873. X    }
  1874. X
  1875. X    n -= 2 ;
  1876. X    check = 0 ;
  1877. X
  1878. X    for (i = 0 ; i < n ; i++) check = 17 * check + buf[i] ;
  1879. X
  1880. X    if    (    ((check & 0x3f) + BASE) != buf[n]
  1881. X        ||    (((check >>= 6) & 0x3f) + BASE) != buf[n+1]
  1882. X        )
  1883. X    {
  1884. X        (void) fprintf(stderr, "Text checksum error!\n", prefix) ;
  1885. X        return ;
  1886. X    }
  1887. X
  1888. X    buf[n] = 0 ;
  1889. X
  1890. X    if (prefix == '!') (void) system(buf) ;
  1891. X
  1892. X    if (prefix == '#')
  1893. X    {
  1894. X        (void) fputs(buf, stderr) ;
  1895. X        (void) fputc('\n', stderr) ;
  1896. X    }
  1897. X}
  1898. X
  1899. X
  1900. X
  1901. X/***********************************************************
  1902. X *    Receive data routine.                                *
  1903. X ***********************************************************/
  1904. X
  1905. Xreceive()
  1906. X{
  1907. X    register int ch ;
  1908. X    register long v ;
  1909. X    int d ;
  1910. X    int i ;
  1911. X    int n ;
  1912. X    int lch ;
  1913. X    unsigned short s ;
  1914. X    ulong real ;
  1915. X    ulong user ;
  1916. X    ulong sys ;
  1917. X    long code ;
  1918. X    long cps ;
  1919. X    long error ;
  1920. X    long trash ;
  1921. X    long scode ;
  1922. X    long incount ;
  1923. X    char buf[200] ;
  1924. X
  1925. X#if BSD
  1926. X    struct timeval tv ;
  1927. X    struct rusage ru ;
  1928. X#else
  1929. X    struct tms tms ;
  1930. X#endif
  1931. X
  1932. X    real = 0 ;
  1933. X    user = 0 ;
  1934. X    sys = 0 ;
  1935. X    trash = 0 ;
  1936. X    error = 0 ;
  1937. X    code = MAXCODE - 1 ;
  1938. X    scode = 0 ;
  1939. X    incount = 0 ;
  1940. X
  1941. X    ch = getc(stdin) ;
  1942. X
  1943. X    /*
  1944. X     *    Loop to read codes until and exit code appears.
  1945. X     */
  1946. X
  1947. X    for (;;)
  1948. X    {
  1949. X        v = 0 ;
  1950. X        d = 0 ;
  1951. X        s = 0 ;
  1952. X
  1953. X        if (++incount >= throttle)
  1954. X        {
  1955. X            (void) sleep(1) ;
  1956. X            incount = 0 ;
  1957. X        }
  1958. X
  1959. X        /*
  1960. X         *    Ignore white space, detect EOF, and scan
  1961. X         *    until a digit appears.
  1962. X         */
  1963. X
  1964. X        lch = '\n' ;
  1965. X
  1966. X        for (;;)
  1967. X        {
  1968. X            if (ch == EOF)
  1969. X            {
  1970. X                if (!silent) (void) fprintf(stderr, "Exiting on EOF!\n") ;
  1971. X                exit(1) ;
  1972. X            }
  1973. X
  1974. X            ch &= 0x7f ;
  1975. X
  1976. X            if (ch >= '0' && ch <= '9') break ;
  1977. X
  1978. X            if (lch == '\n' && (ch == '!' || ch == '#'))
  1979. X            {
  1980. X                readtext(ch) ;
  1981. X                lch = '\n' ;
  1982. X            }
  1983. X            else if
  1984. X                (    ch != '\r' && ch != '\n'
  1985. X                &&    (ch < BASE || ch > (BASE + 0x3f))
  1986. X                )
  1987. X                trash++ ;
  1988. X
  1989. X            lch = '\n' ;
  1990. X            ch = getc(stdin) ;
  1991. X        }
  1992. X
  1993. X        /*
  1994. X         *    Pick up a digit string.
  1995. X         */
  1996. X
  1997. X        while (isdigit(ch))
  1998. X        {
  1999. X            ch -= '0' ;
  2000. X            v = 10 * v + ch ;
  2001. X            s += (s << 4) + ch ;
  2002. X            d++ ;
  2003. X            if ((ch = getc(stdin)) == EOF) break ;
  2004. X            ch &= 0x7f ;
  2005. X        }
  2006. X
  2007. X        /*
  2008. X         *    Process checksum.
  2009. X         */
  2010. X
  2011. X        if (d != NDIG || (ch - BASE) != (s & 0x3f)) continue ;
  2012. X
  2013. X        if ((ch = getc(stdin)) == EOF) continue ;
  2014. X        ch &= 0x7f ;
  2015. X
  2016. X        if ((ch - BASE) != ((s >> 6) & 0x3f)) continue ;
  2017. X
  2018. X        ch = getc(stdin) ;
  2019. X
  2020. X        /*
  2021. X         *    Pick up end of sequence or quit indicator.
  2022. X         */
  2023. X
  2024. X        if (v >= MAXCODE - 1)
  2025. X        {
  2026. X            if (code != MAXCODE - 1)
  2027. X            {
  2028. X                code -= scode ;
  2029. X
  2030. X                /*
  2031. X                 *    Figure resources used, and print results.
  2032. X                 */
  2033. X
  2034. X#if BSD
  2035. X                (void) gettimeofday(&tv, (struct timezone *)0) ;
  2036. X                real = MS(tv) - real ;
  2037. X
  2038. X                (void) getrusage(RUSAGE_SELF, &ru) ;
  2039. X                user = MS(ru.ru_utime) - user ;
  2040. X                sys = MS(ru.ru_stime) - sys ;
  2041. X                cps = 1000L * NCHAR(code) / (real ? real : 1) ;
  2042. X#else
  2043. X                real = times(&tms) - real ;
  2044. X                cps = TICS * NCHAR(code) / (real ? real : 1) ;
  2045. X                user = tms.tms_utime - user ;
  2046. X                sys = tms.tms_stime - sys ;
  2047. X#endif
  2048. X                if (real == 0) real = 1 ;
  2049. X
  2050. X                (void) sprintf(buf,
  2051. X                    "%s : IN  cps=%ld, real=%.2f, user=%.1f, sys=%.1f, errs=%ld, stray=%ld\n",
  2052. X                    tname, cps, (double)real / TICS,
  2053. X                    100.0 * (double) user / (double) real,
  2054. X                    100.0 * (double) sys / (double) real,
  2055. X                    error, trash) ;
  2056. X                
  2057. X                (void) write(2, buf, (unsigned) strlen(buf)) ;
  2058. X
  2059. X                /*
  2060. X                 *    Print verbose error statistics.
  2061. X                 */
  2062. X
  2063. X                if (verbose && error)
  2064. X                {
  2065. X                    (void) fprintf(stderr,
  2066. X                        "%s : Sequence gaps were:\n\t", tname) ;
  2067. X
  2068. X                    n = 0 ;
  2069. X                    for (i = 0 ; i < MAXSTAT ; i++)
  2070. X                    {
  2071. X                        if (gap[i])
  2072. X                        {
  2073. X                            if (n == 6)
  2074. X                            {
  2075. X                                (void) fprintf(stderr, "\n\t") ;
  2076. X                                n = 0 ;
  2077. X                            }
  2078. X                            (void) fprintf(stderr,
  2079. X                                "%4d:%4d", NCHAR(i+1), gap[i]) ;
  2080. X                            n++ ;
  2081. X                        }
  2082. X                    }
  2083. X                    if (n) (void) fprintf(stderr, "\n") ;
  2084. X                }
  2085. X            }
  2086. X
  2087. X            /*
  2088. X             *    Quit when the maximum input code is
  2089. X             *    received.
  2090. X             */
  2091. X
  2092. X            if (v == MAXCODE)
  2093. X            {
  2094. X                (void) fprintf(stderr,
  2095. X                    "%s : Received exit code, quitting\n", tname) ;
  2096. X                exit(0) ;
  2097. X            }
  2098. X            if (code != MAXCODE - 1)
  2099. X            {
  2100. X                code = MAXCODE - 1 ;
  2101. X            }
  2102. X        }
  2103. X
  2104. X        /*
  2105. X         *    Handle expected sequence number.
  2106. X         */
  2107. X
  2108. X        else if (v == code) code++ ;
  2109. X
  2110. X        /*
  2111. X         *    Handle sequence lower than our current sequence,
  2112. X         *    indicating a restart.
  2113. X         */
  2114. X
  2115. X        else if (v < code)
  2116. X        {
  2117. X            if (code != MAXCODE - 1)
  2118. X            {
  2119. X                (void) fprintf(stderr,
  2120. X                    "%s : Incomplete sequence aborted\n", tname) ;
  2121. X            }
  2122. X
  2123. X            for (i = 0 ; i < MAXSTAT ; i++) gap[i] = 0 ;
  2124. X
  2125. X            trash = 0 ;
  2126. X            error = 0 ;
  2127. X            code = v + 1 ;
  2128. X
  2129. X            /*
  2130. X             *    Get start time statistics.
  2131. X             */
  2132. X
  2133. X#if BSD
  2134. X            (void) gettimeofday(&tv, (struct timezone *)0) ;
  2135. X            real = MS(tv) ;
  2136. X
  2137. X            (void) getrusage(RUSAGE_SELF, &ru) ;
  2138. X            user = MS(ru.ru_utime) ;
  2139. X            sys = MS(ru.ru_stime) ;
  2140. X#else
  2141. X            real = times(&tms) ;
  2142. X            user = tms.tms_utime ;
  2143. X            sys = tms.tms_stime ;
  2144. X#endif
  2145. X
  2146. X            scode = v ;
  2147. X        }
  2148. X
  2149. X        /*
  2150. X         *    Handle sequence greater than our expected
  2151. X         *    sequence.
  2152. X         */
  2153. X
  2154. X        else
  2155. X        {
  2156. X            i = v - code ;
  2157. X            error += i ;
  2158. X            if (i > MAXSTAT) i = MAXSTAT ;
  2159. X            gap[i-1]++ ;
  2160. X            code = v + 1 ;
  2161. X        }
  2162. X    }
  2163. X}
  2164. X
  2165. X
  2166. X
  2167. X/*************************************************************
  2168. X *        Main Program                                       *
  2169. X *************************************************************/
  2170. X
  2171. Xmain(argc, argv)
  2172. Xint argc ;
  2173. Xchar **argv ;
  2174. X{
  2175. X    int quit = 0 ;
  2176. X    int i ;
  2177. X    int ch ;
  2178. X    long nchar ;
  2179. X
  2180. X#if SETVBUF
  2181. X    (void) setvbuf(stdin,  _IOFBF, iobuf[0], sizeof(iobuf[0])) ;
  2182. X    (void) setvbuf(stdout, _IOFBF, iobuf[1], sizeof(iobuf[0])) ;
  2183. X    (void) setvbuf(stderr, _IOLBF, iobuf[2], sizeof(iobuf[0])) ;
  2184. X#else
  2185. X    (void) setvbuf(stdin,  iobuf[0], _IOFBF, sizeof(iobuf[0])) ;
  2186. X    (void) setvbuf(stdout, iobuf[1], _IOFBF, sizeof(iobuf[0])) ;
  2187. X    (void) setvbuf(stderr, iobuf[2], _IOLBF, sizeof(iobuf[0])) ;
  2188. X#endif
  2189. X
  2190. X    /*
  2191. X     *    Break out options.
  2192. X     */
  2193. X    
  2194. X    throttle = 9999999 ;
  2195. X
  2196. X    while ((ch = getopt(argc, argv, "c:e:qst:vx:")) != -1)
  2197. X    {
  2198. X        switch (ch)
  2199. X        {
  2200. X        case 'c':
  2201. X            out++ ;
  2202. X            sendtext('!', optarg) ;
  2203. X            break ;
  2204. X        
  2205. X        case 'e':
  2206. X            out++ ;
  2207. X            sendtext('#', optarg) ;
  2208. X            break ;
  2209. X
  2210. X        case 'q':
  2211. X            out++ ;
  2212. X            quit++ ;
  2213. X            break ;
  2214. X        
  2215. X        case 's':
  2216. X            silent++ ;
  2217. X            break ;
  2218. X
  2219. X        case 't':
  2220. X            throttle = atoi(optarg) ;
  2221. X            throttle = NCODE(throttle) ;
  2222. X            break ;
  2223. X
  2224. X        case 'v':
  2225. X            verbose++ ;
  2226. X            break ;
  2227. X        
  2228. X        case 'x':
  2229. X            out++ ;
  2230. X            nchar = atoi(optarg) ;
  2231. X            transmit(NCODE(nchar)) ;
  2232. X            break ;
  2233. X        
  2234. X        default:
  2235. X            (void) fprintf(stderr,
  2236. X                "usage: %s [ -qv ] [ nchar ]\n", argv[0]) ;
  2237. X            exit(2) ;
  2238. X        }
  2239. X    }
  2240. X    
  2241. X    /*
  2242. X     *    Check for terminal input/output.
  2243. X     */
  2244. X
  2245. X    if (optind != argc) out++ ;
  2246. X
  2247. X    if (out)
  2248. X    {
  2249. X        tname = ttyname(1) ;
  2250. X        if (tname == 0)
  2251. X        {
  2252. X            if (!silent)
  2253. X                (void) fprintf(stderr, "Standard output is not a terminal!\n") ;
  2254. X            tname = "OUTPUT" ;
  2255. X        }
  2256. X    }
  2257. X    else
  2258. X    {
  2259. X        tname = ttyname(0) ;
  2260. X        if (tname == 0)
  2261. X        {
  2262. X            if (!silent)
  2263. X                (void) fprintf(stderr, "Standard input is not a terminal!\n") ;
  2264. X            tname = "INPUT" ;
  2265. X        }
  2266. X    }
  2267. X
  2268. X    /*
  2269. X     *    Output code counts as requested.
  2270. X     */
  2271. X
  2272. X    while (optind < argc)
  2273. X    {
  2274. X        nchar = atol(argv[optind]) ;
  2275. X        if (nchar > 0) transmit(NCODE(nchar)) ;
  2276. X        optind++ ;
  2277. X    }
  2278. X
  2279. X    /*
  2280. X     *    Output quit codes.
  2281. X     */
  2282. X
  2283. X    if (quit)
  2284. X    {
  2285. X        for (i = 0 ; i < NTRAIL ; i++)
  2286. X        {
  2287. X            outcode((long) MAXCODE) ;
  2288. X        }
  2289. X        closeline() ;
  2290. X    }
  2291. X
  2292. X    (void) fflush(stdout) ;
  2293. X
  2294. X    /*
  2295. X     *    If no code counts or the quit flag, this is
  2296. X     *    a receive data test.
  2297. X     */
  2298. X
  2299. X    if (!out)
  2300. X    {
  2301. X        receive() ;
  2302. X        exit(0) ;
  2303. X    }
  2304. X
  2305. X    return(0) ;
  2306. X}
  2307. END_OF_perf.c
  2308. if test 16238 -ne `wc -c <perf.c`; then
  2309.     echo shar: \"perf.c\" unpacked with wrong size!
  2310. fi
  2311. # end of overwriting check
  2312. fi
  2313. echo shar: End of shell archive.
  2314. exit 0
  2315.  
  2316.